构建一本书

构建一本书

我正在为我的 CS 同学写一些笔记,我对以下领域感兴趣:

  • 它是否遵循良好的代码实践?
  • 这本书/笔记/文件的结构是否良好?
  • 是否存在“不可原谅”的代码片段?
  • 我是否正确使用了图形环境?
  • \frontmatter和位置是否\mainmatter正确?
  • 还有什么需要改进吗?

我将向您展示主文件的代码和章节的代码。该章节并非完全真实,因此,如果英文和中文混杂在一起,请不要害怕加泰罗尼亚语。我发明它只是为了让你分析我的章节结构(每章都有相同的结构:算法解释+最后一节=C++ 代码带有lstlistingC++ 代码的 s。我使用了几个定理框,例如defi(定义)、conv(约定)和prob(问题)。

我已经上传了生成的 PDF在我的个人 Dropbox 中(和在第三方网站上),以便您可以查看整个文档。

notes.tex这是文件(主文件)的代码。

% Compile with pdflatex
\documentclass[a4paper, 12pt, titlepage]{book}

% LINKS
\usepackage{xcolor}
\usepackage{hyperref}
\hypersetup{
    colorlinks,
    linkcolor={red!60!black},
    citecolor={blue!50!black},
    urlcolor={blue!30!black}
}


% PAGE STRUCTURE
\usepackage{geometry}
\setcounter{tocdepth}{1} % Just chapters and sections


% TYPOGRAPHY
% Encoding
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

% Math fonts
\usepackage{amsmath}
\usepackage{amssymb}

% Text fonts
\usepackage{mathpazo}    % Palatino fallback
\usepackage{newtxtext}   % ~Times for text
\usepackage{newtxmath}   % ~Times for math
\usepackage{inconsolata} % Monospaced font

% Text tricks
\usepackage{microtype}
\usepackage[parfill]{parskip}


% LANGUAGE
\usepackage[catalan]{babel}
\addto\captionscatalan{\renewcommand{\chaptername}{Tema}}


% THEOREMS
\usepackage{mdframed}
\mdfsetup{leftline=false, rightline=false, linecolor=gray,
    linewidth=1pt, skipabove=\topskip, skipbelow=\topskip,
    innerleftmargin=0, innerrightmargin=0}
\newmdtheoremenv{prob}{Problem}
\newmdtheoremenv{defi}{Theorem}
\newmdtheoremenv{conv}{Convention}


% FIGURES
% Images
\usepackage[demo]{graphicx} % Just demo for the question

% Code
\usepackage{listings}
\lstset{
    language          = C++,
    columns           = fullflexible,
    identifierstyle   = \itshape,
    keywordstyle      = \bfseries\color{blue!50!black},
    frame             = tb,
    rulecolor         = \color{blue!20!black},
    framerule         = 1pt,
    showstringspaces  = false,
    tabsize           = 4,
    morekeywords      = {pair, vector, list, set, graph, stack,
                         queue, priority_queue, iterator, const_iterator},
    framexleftmargin  = 1em,
    framexrightmargin = 1em,
    literate          = {<=}{{$\leq$ }}1 
                        {>=}{{$\geq$ }}1 
                        {!=}{{$\neq$ }}1    % transform {<=, >=, !=} to {≤, ≥, ≠}.
}


% MY COMMANDS
% Math shortcuts
\renewcommand{\o}{\ensuremath{\mathrm o}}           % Little-o notation
\renewcommand{\O}{\ensuremath{\mathrm O}}           % Big-o notation
\newcommand{\twodots}{\mathinner{\ldotp \ldotp}}    % Use in subvectors v[i..j]


% TITLE
% First page decoration
\newcommand{\titledecoration}{%
    {\fontsize{72}{70}\selectfont\color{gray}$\Theta(n \log n)$}\\[5em]
}

% Title, author, date
\title{\titledecoration%
    A Very Important Subject}
\author{My Name and Surname}
\date{Fall Semester (2016--17)\\
    My City Schools of Informatics (MCSI)\\
    Worldwide University of the Univers (WUU)}

% I just include this package for this question!!
\usepackage{lipsum}

\begin{document}
    % FIRST PAGES
    \frontmatter

    % First page: title
    \newgeometry{margin=1.5in}
    \maketitle
    \restoregeometry

    % Second page: copyright
    \null\vfill
    \includegraphics{copy.png}

    All rights reserved. No part of this book may be
    reproduced in any form or by any electronic... % etcetera

    \url{https://creativecommons.org/licenses/by-nd/4.0/deed.ca}

    % Preface
    \chapter{Prefaci}

    \textbf{Why do I write these notes?}
    \begin{itemize}
        \item ...
        \item ...
        \item ...
    \end{itemize}

    \textbf{Sources and bibliography}
    % Ok, I should use \bibliography, but I just
    % have to cite a few sources (4 or 5).
    \begin{itemize}
        \item ...
        \item ...
        \item ...
        \item ...
    \end{itemize}

    \textbf{Book structure}
    \begin{itemize}
        \item ...
        \item ...
    \end{itemize}

    \begin{description}
        \item[Contact mail] \ 

        \href{mailto:[email protected]}{[email protected]}
    \end{description}

    % toc
    \tableofcontents

    % CHAPTERS
    \mainmatter
    \include{cap1}
    \include{cap2}
    \include{cap3}
    % and so on

\end{document}

这里是单个章节的代码,假设是cap1.tex。我强烈建议你将其与我之前为你链接的 PDF 进行比较。此外,还有很多从真实文档中提取的虚拟文本,因此你只需使用%浏览器搜索注释(搜索符号)即可扫描它。它们是故意设置的。

\chapter{Asymptotic notation}

\section{Cost in time and space}
\lipsum[4-6]

\section{Cas pitjor, millor i mitjà}
Trobar la funció $T$ anterior pot ser complicat. Ens interessarem només per aquells conjunts d'entrades que tinguin mida $n$.

% Use of definition

\begin{defi}
    Sigui $\mathcal A_n$ el conjunt d'entrades de mida $n$ i sigui $T_n: \mathcal A_n \to \mathbb R$ la funció $T$ restringida a $\mathcal A_n$. Els costos en cas pitjor, millor i mitjà es defineixen com segueix.

    \begin{description}
        \item[Cost en cas pitjor] $T_\text{pitjor}(n) = \max \{T_n(\alpha) \colon \alpha \in \mathcal A_n\}$
        \item[Cost en cas millor] $T_\text{millor}(n) = \min \{T_n(\alpha) \colon \alpha \in \mathcal A_n\}$
        \item[Cost en cas mitjà] $T_\text{mitjà}(n) = \sum_{\alpha \in \mathcal A_n} [ \Pr(\alpha) \cdot T_n (\alpha) ]$, on $\Pr(\alpha)$ és la probabilitat d'ocurrència de l'entrada $\alpha$.
    \end{description}
\end{defi}

\lipsum[8]

\section{Convencions}
Tot i que $\O,$ $\dots$, $\omega$ són \textit{conjunts} de funcions, i, donada una funció $f\colon \mathbb N \to \mathbb R$, s'ha d'escriure $f \in \O(g)$, per a certa funció $g$, sovint no es fa servir aquesta notació.

% Use of convention

\begin{conv}
    Siguin $f$ i $g$ funcions i $X$ qualsevol dels conjunts $\O$, $\dots$, $\omega$. Entenem que l'abús de notació $f = X(g)$ significa $f \in X(g)$.

    Per tant, podem escriure $3n^2 = \Theta(n^2)$, $n \log n = \omega (100 n)$, etc. Aquesta convenció, però, no és commutativa: es pot dir $n = \O(n^2)$, però no té cap sentit escriure $\O(n^3) = 10n^2 - 5n$.
\end{conv}

En fórmules de recurrència, de vegades necessitarem escriure expressions com
\[ T(n) = T(n/2) + \Theta(1) \]
Aquest $\Theta(1)$ s'ha d'entendre com ``qualsevol funció $f(n)$ tal que $f = \Theta(1)$''.

\begin{conv}
    Podem interpretar $f \star X(g)$ com ``$f \star h$, per a qualsevol funció $h$ tal que $h = X(g)$'', on $\star$ és qualsevol operador binari i $X$ és qualsevol dels conjunts $\O, \dots, \omega$.
\end{conv}

\section{\textit{Quicksort}} % Quicksort is a foreign term in catalan
El problema és el d'ordenar un vector $v$ de mida $n$ (vegeu el problema \ref{prob:ordenar}).

Les fases de dividir i vèncer són:
\begin{enumerate}
    \item \textit{Divisió}: particionar $v$ en dos subvectors no buits $v_l$ i $v_r$ de la següent manera.

    Sigui $0 \leq i < n$. Volem trobar l'índex $i$ de $v$ tal que $v_l = v[0 \twodots i]$, $v_r = v[i+1 \twodots n-1]$, i tot element de $v_l$ és menor o igual que tot element de $v_r$. És a dir, \[\forall a \in [0, i] \text{ i } \forall b\in[i+1, n-1]\text{, es verifica que } v[a] \leq v[b]\]

    La primera implementació d'aquest procediment (\textit{partició}) la va inventar en C. A. R. Hoare. Es fa escollint un pivot (per exemple, $v[0]$) i comparant la resta d'elements amb aquest.
    \item \textit{Resolució}: ordenar recursivament $v_l$ i $v_r$
    \item \textit{Combinació}: atès que $v_l$ i $v_r$ estan ordenats, per ordenar $v$ no cal fer res.
\end{enumerate}

% Reference to a full-page figure

El cost de l'algorisme (vegeu \figurename~\ref{fig:quicksort}) és $\Theta(1)$ per a $n = 1$, i, per a $n \geq 2$:
\[ T(n) = T(k) + T(n-k) + \Theta(n) \]
amb $1 \leq k \leq n-1$.

La solució de la recurrència depèn de $k$:

\begin{description}
    \item[En cas pitjor] $\Theta(n^2)$. És la situació en què $k = 1$; la partició ha estat molt dolenta: hem particionat $v$ en un subvector amb 1 element i en un altre subvector amb els $n-1$ elements restants. És el cas en què el vector d'entrada ja està ordenat (creixentment o decreixent).
    \item[En cas millor] $\Theta(n \log n)$. És la solució de la recurrència amb $k = 2$. Intuïtivament, $k = 2$ proporciona la millor partició: $v_l$ i $v_r$ tenen, ambdós com a molt $\lceil n/2 \rceil$ elements; $v$ es parteix per la meitat. 
    \item[En cas mitjà] $\Theta(n \log n)$. Cal suposar una distribució de probabilitat de les entrades. Se sol suposar que totes les permutacions del vector d'entrada són equiprobables i que, per tant, tots els elements tenen la mateixa probabilitat ($1/n$) de ser el pivot.
\end{description}

% A trick to force the figure
% to appear in the following page
\clearpage
\begin{figure}[p!]
    \centering
    \includegraphics{quicksort.png}
    \vspace{1cm}
    \caption{\label{fig:quicksort}Sorting a vector $v$ using \textit{quicksort}.}
\end{figure}
\clearpage

\section{Dummy section}
\lipsum[3-6]


\section{Codes in C++}
% This is a section where I include C++ codes of the algorithms explained
% in the previous sections.
% I also add, here, some implementation tips in the following itemize:
\begin{itemize}
    \item \lipsum[12]
    \item \lipsum[12]
    % Maybe a crossed reference.
    \item \lipsum[12] See \figurename~\ref{fig:helloworld} for more information.
\end{itemize}

% And, at this point, I use p! and b! in order to get
% a pleasant distribution of code snippets

\begin{figure}[b!]
    % I usually input code by
    % \lstinputlisting{namefile.cc}
    \begin{lstlisting}
#include <iostream>
using namespace std;

int main()
{
    cout << "Most difficult code ever" << endl;
}
    \end{lstlisting}
    \caption{\label{fig:helloworld} The most incredible C++ code ever.}
\end{figure}

% Now an example of my lstlisting options.

\begin{figure}[b!]
    \begin{lstlisting}
#include <iostream>
#include <vector>
using namespace std;

void noncompilant_function() {
    int x = 3;
    double t = 2;
    if (stack<int> != priority_queue<double, int>) {
        for (vector<int>::const_iterator it = b.begin(); it != b.end(); ++it) {
            M[i][j] <= a >= b;
        }
    }
}


// This is a short comment
/* And this is a larger one */
int main() {
    int n, m;
    while (cin >> n >> m) {
        vector<pair<int, int>> amb_lletres;
        for (int i = 0; i <= n; --i) {
            for (int j = 0; j >= m; ++j) {
                if (M[i][j] != M[j][i]) {
                    continue;
                }
            }
        }
    }
}
    \end{lstlisting}
    \caption{\label{fig:lstlistexplained} A C++ code that doesn't work at all}
\end{figure}

% And keep inserting figures as the following one:
%\begin{figure}[p]
%   \lstinputlisting{karatsuba.cc}
%   \caption{Implementació en C++ de l'algorisme de Karatsuba
%   \label{fig:karatsuba}}                       
%\end{figure}

任何答案都会对我有帮助。

答案1

很难写出一个好的答案,因为你问的很多问题都涉及很多观点,而不是可引用和可支持的事实。不过,我会尽我所能给出最好的答案。

关于良好的代码实践,如果这将成为未来许多文档的基础,您可能需要定义一个新的类(*.cls文件类型)。至少,所有您不打算更改的前置内容都应移至样式(文件类型)*.sty。有关更多详细信息,您可以阅读此文档两者之间的区别。

此外,对于输入到文档中的文本,过去的做法是尽量将每行文本限制在 72 个字符以内。下面是我从旧模板中复制的标题的一部分:

% ---------------------------------------------------------------------|
% --------------------------- 72 characters ---------------------------|
% ---------------------------------------------------------------------|

虽然这个限制不是必需的,但我发现在创建文档时区分我的自由形式的写作和我已审阅并完成至少一个校对阶段的部分很有帮助。

关于你的代码是否“漂亮”,除了遵循一般的编码实践之外,我找不到格式化的样式指南LaTeX。@jon 和 @barbara beeton 已经提供了关于优先顺序避免使用单字母宏也很重要。

关于文档的整体结构,LaTeX我会为您完成。如果您以以下格式设置文件,则可能更容易维护所需的结构:

\begin{document}
\frontmatter
\pagestyle{plain}
\include{./TeX_files/Frontpages}
\tableofcontents
\listoftables
\listoffigures

\mainmatter
\pagestyle{fancy}
\include{./TeX_files/First_Chapter}
\include{./TeX_files/Next_Chapter}
\include{./TeX_files/Later_Chapter}
\include{./TeX_files/Last_Chapter}

\backmatter
\include{./TeX_files/Appendix_Chapter}
\include{./TeX_files/Bibliography}
\printglossary
\include{./TeX_files/backpages}
\end{document}

环境的格式figure应为:

\begin{figure}[tbph]
\centering
\includegraphics[size specification]{./Images/Figure}
\caption{Caption of the figure/float}
\label{fig:Figure}
\end{figure}

我不确定为什么你会希望将信息放在浮点数中而不是直接定义,但可以将浮点数用于实际图形以外的目的。label永远不应该在 内caption。 我最喜欢的此类格式信息的权威来源可以在这里找到:https://en.wikibooks.org/wiki/LaTeX/Floats,_Figures_and_Captions

相关内容